home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / ASCIITransfer.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  20KB  |  1,104 lines

  1. /*
  2. **    ASCIITransfer.c
  3. **
  4. **    ASCII file transfer routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* Local variables. */
  17.  
  18. STATIC UBYTE    ASCIISendPrompt[256];
  19. STATIC LONG        ASCIISendPromptLen;
  20. STATIC SENDLINE    ASCIISendLine;
  21.  
  22. STATIC LONG
  23. MangleASCIIBuffer(BYTE TranslateCR,BYTE TranslateLF,STRPTR Source,LONG SourceLen,STRPTR Destination)
  24. {
  25.     LONG    CR_Len,
  26.             LF_Len;
  27.     STRPTR    CR_String,
  28.             LF_String;
  29.     LONG    Mask;
  30.     LONG    Len = 0;
  31.  
  32.     switch(TranslateCR)
  33.     {
  34.         case EOL_IGNORE:
  35.  
  36.             CR_Len = 0;
  37.             break;
  38.  
  39.         case EOL_CR:
  40.  
  41.             CR_Len        = 1;
  42.             CR_String    = "\r";
  43.             break;
  44.  
  45.         case EOL_LF:
  46.  
  47.             CR_Len        = 1;
  48.             CR_String    = "\n";
  49.             break;
  50.  
  51.         case EOL_CRLF:
  52.  
  53.             CR_Len        = 2;
  54.             CR_String    = "\r\n";
  55.             break;
  56.  
  57.         case EOL_LFCR:
  58.  
  59.             CR_Len        = 2;
  60.             CR_String    = "\n\r";
  61.             break;
  62.     }
  63.  
  64.     switch(TranslateLF)
  65.     {
  66.         case EOL_IGNORE:
  67.  
  68.             LF_Len = 0;
  69.             break;
  70.  
  71.         case EOL_LF:
  72.  
  73.             LF_Len        = 1;
  74.             LF_String    = "\n";
  75.             break;
  76.  
  77.         case EOL_CR:
  78.  
  79.             LF_Len        = 1;
  80.             LF_String    = "\r";
  81.             break;
  82.  
  83.         case EOL_LFCR:
  84.  
  85.             LF_Len        = 2;
  86.             LF_String    = "\n\r";
  87.             break;
  88.  
  89.         case EOL_CRLF:
  90.  
  91.             LF_Len        = 2;
  92.             LF_String    = "\r\n";
  93.             break;
  94.     }
  95.  
  96.     if(Config->TransferConfig->StripBit8)
  97.         Mask = 0x7F;
  98.     else
  99.         Mask = 0xFF;
  100.  
  101.     do
  102.     {
  103.         switch(*Source)
  104.         {
  105.             case '\r':
  106.  
  107.                 if(CR_Len)
  108.                 {
  109.                     if(Len >= CR_Len && Config->TransferConfig->ExpandBlankLines)
  110.                     {
  111.                         if(!memcmp(&Destination[-CR_Len],CR_String,CR_Len))
  112.                         {
  113.                             *Destination++ = ' ';
  114.                             Len++;
  115.                         }
  116.                     }
  117.  
  118.                     CopyMem(CR_String,Destination,CR_Len);
  119.  
  120.                     Destination    += CR_Len;
  121.                     Len            += CR_Len;
  122.                 }
  123.  
  124.                 break;
  125.  
  126.             case '\n':
  127.  
  128.                 if(LF_Len)
  129.                 {
  130.                     if(Len >= LF_Len && Config->TransferConfig->ExpandBlankLines)
  131.                     {
  132.                         if(!memcmp(&Destination[-LF_Len],LF_String,LF_Len))
  133.                         {
  134.                             *Destination++ = ' ';
  135.                             Len++;
  136.                         }
  137.                     }
  138.  
  139.                     CopyMem(LF_String,Destination,LF_Len);
  140.  
  141.                     Destination    += LF_Len;
  142.                     Len            += LF_Len;
  143.                 }
  144.  
  145.                 break;
  146.  
  147.             default:
  148.  
  149.                 *Destination++ = (*Source) & Mask;
  150.  
  151.                 Len++;
  152.  
  153.                 break;
  154.         }
  155.  
  156.         Source++;
  157.     }
  158.     while(--SourceLen);
  159.  
  160.     return(Len);
  161. }
  162.  
  163.     /* WaitForPrompt(STRPTR Prompt,LONG PromptLen):
  164.      *
  165.      *    Scan the incoming data flow for a certain string.
  166.      */
  167.  
  168. STATIC BOOL
  169. WaitForPrompt(STRPTR Prompt,LONG PromptLen)
  170. {
  171.     ULONG Signals;
  172.     BOOL GotIt;
  173.  
  174.         /* Reset the match data. */
  175.  
  176.     MatchPrompt(NULL,0,NULL,0);
  177.  
  178.         /* Start the timer. */
  179.  
  180.     StartTime(Config->TransferConfig->SendTimeout / 100,(Config->TransferConfig->SendTimeout % 100) * 10000);
  181.  
  182.         /* Lock the current xOFF state and clear the xOFF flag. */
  183.  
  184.     Lock_xOFF();
  185.     Clear_xOFF();
  186.  
  187.     GotIt = FALSE;
  188.  
  189.         /* Loop until the prompt is found or the timer elapses. */
  190.  
  191.     do
  192.     {
  193.         Signals = (*SerialWaitForData)(SIG_TIMER);
  194.  
  195.             /* New serial data available? */
  196.  
  197.         if(Signals & SIG_SERIAL)
  198.         {
  199.             ULONG Length;
  200.  
  201.                 /* Check how much data is available. */
  202.  
  203.             if(Length = (*SerialGetWaiting)())
  204.             {
  205.                     /* Don't read more than the buffer will hold. */
  206.  
  207.                 if(Length > SerialBufferSize)
  208.                     Length = SerialBufferSize;
  209.  
  210.                     /* Read the data. */
  211.  
  212.                 if(Length = (*SerialRead)(ReadBuffer,Length))
  213.                 {
  214.                         /* Got some more data. */
  215.  
  216.                     BytesIn += Length;
  217.  
  218.                     if(!Config->TransferConfig->QuietTransfer)
  219.                         ConProcess(ReadBuffer,Length);
  220.  
  221.                         /* Check if this is it. */
  222.  
  223.                     if(MatchPrompt(ReadBuffer,Length,Prompt,PromptLen))
  224.                         GotIt = TRUE;
  225.                 }
  226.             }
  227.         }
  228.  
  229.             /* Stop if the bell rings. */
  230.  
  231.         if(Signals & SIG_TIMER)
  232.             break;
  233.     }
  234.     while(!GotIt);
  235.  
  236.         /* Stop the timer. */
  237.  
  238.     StopTime();
  239.  
  240.         /* Unlock the xOFF state. */
  241.  
  242.     Unlock_xOFF();
  243.  
  244.     return(GotIt);
  245. }
  246.  
  247.     /* ASCIISendLinePrompt(STRPTR Line,LONG Len):
  248.      *
  249.      *    Send text line, wait for prompt.
  250.      */
  251.  
  252. STATIC BOOL
  253. ASCIISendLinePrompt(STRPTR Line,LONG Len)
  254. {
  255.     LONG i;
  256.  
  257.     if(Len == -1)
  258.         Len = strlen(Line);
  259.  
  260.     while(Len)
  261.     {
  262.         i = 0;
  263.  
  264.         while(i < Len && Line[i] != '\r')
  265.             i++;
  266.  
  267.         if(Line[i] == '\r')
  268.         {
  269.             i++;
  270.  
  271.             SerWrite(Line,i);
  272.  
  273.             if(!WaitForPrompt(ASCIISendPrompt,ASCIISendPromptLen))
  274.                 return(FALSE);
  275.         }
  276.         else
  277.         {
  278.             if(i)
  279.                 SerWrite(Line,i);
  280.         }
  281.  
  282.         Len        -= i;
  283.         Line    += i;
  284.     }
  285.  
  286.     return(TRUE);
  287. }
  288.  
  289.     /* ASCIISendLineDelay(STRPTR Line,LONG Len):
  290.      *
  291.      *    Send a text line, include a delay where necessary.
  292.      */
  293.  
  294. STATIC BOOL
  295. ASCIISendLineDelay(STRPTR Line,LONG Len)
  296. {
  297.     if(Len == -1)
  298.         Len = strlen(Line);
  299.  
  300.     while(Len--)
  301.     {
  302.         SerWrite(Line,1);
  303.  
  304.         if(*Line == '\r')
  305.             DelayTime(Config->TransferConfig->LineDelay / 100,(Config->TransferConfig->LineDelay % 100) * 10000);
  306.         else
  307.             DelayTime(Config->TransferConfig->CharDelay / 100,(Config->TransferConfig->CharDelay % 100) * 10000);
  308.  
  309.         Line++;
  310.     }
  311.  
  312.     return(TRUE);
  313. }
  314.  
  315.     /* ASCIISendLineEcho(STRPTR Line,LONG Len):
  316.      *
  317.      *    Send a text line, wait for single characters to be echoed.
  318.      */
  319.  
  320. STATIC BOOL
  321. ASCIISendLineEcho(STRPTR Line,LONG Len)
  322. {
  323.     ULONG Signals;
  324.     BOOL GotIt;
  325.  
  326.         /* -1 means we are going to scan for a null-terminated string. */
  327.  
  328.     if(Len == -1)
  329.         Len = strlen(Line);
  330.  
  331.         /* Lock the current xOFF state and clear the xOFF flag. */
  332.  
  333.     Lock_xOFF();
  334.     Clear_xOFF();
  335.  
  336.     while(Len--)
  337.     {
  338.             /* Write the next character. */
  339.  
  340.         SerWrite(Line,1);
  341.  
  342.             /* Start the timer. */
  343.  
  344.         StartTime(Config->TransferConfig->SendTimeout / 100,(Config->TransferConfig->SendTimeout % 100) * 10000);
  345.  
  346.             /* Loop until we got an echo or the bell rings. */
  347.  
  348.         GotIt = FALSE;
  349.  
  350.         do
  351.         {
  352.                 /* Wait for something to happen. */
  353.  
  354.             Signals = (*SerialWaitForData)(SIG_TIMER);
  355.  
  356.                 /* Did we receive any data? */
  357.  
  358.             if(Signals & SIG_SERIAL)
  359.             {
  360.                 if((*SerialGetWaiting)())
  361.                 {
  362.                     if((*SerialRead)(ReadBuffer,1))
  363.                     {
  364.                         BytesIn++;
  365.  
  366.                         if(!Config->TransferConfig->QuietTransfer)
  367.                             ConProcess(ReadBuffer,1);
  368.  
  369.                         if(ReadBuffer[0] == *Line)
  370.                             GotIt = TRUE;
  371.                     }
  372.                 }
  373.             }
  374.  
  375.                 /* Did the timer elapse? */
  376.  
  377.             if(Signals & SIG_TIMER)
  378.                 break;
  379.         }
  380.         while(!GotIt);
  381.  
  382.             /* Stop the timer. */
  383.  
  384.         StopTime();
  385.  
  386.             /* Check if we got the echo. If not, return an error. */
  387.  
  388.         if(!GotIt)
  389.         {
  390.             Unlock_xOFF();
  391.             return(FALSE);
  392.         }
  393.  
  394.             /* Skip to the next character in the line. */
  395.  
  396.         Line++;
  397.     }
  398.  
  399.     Unlock_xOFF();
  400.  
  401.     return(TRUE);
  402. }
  403.  
  404.     /* ASCIISendLineAnyEcho(STRPTR Line,LONG Len):
  405.      *
  406.      *    Send a text line, wait for characters to be echoed.
  407.      */
  408.  
  409. STATIC BOOL
  410. ASCIISendLineAnyEcho(STRPTR Line,LONG Len)
  411. {
  412.     ULONG Signals;
  413.     BOOL GotIt;
  414.  
  415.         /* -1 means we are going to scan for a null-terminated string. */
  416.  
  417.     if(Len == -1)
  418.         Len = strlen(Line);
  419.  
  420.         /* Lock the current xOFF state and clear the xOFF flag. */
  421.  
  422.     Lock_xOFF();
  423.     Clear_xOFF();
  424.  
  425.     while(Len--)
  426.     {
  427.             /* Write the next character. */
  428.  
  429.         SerWrite(Line,1);
  430.  
  431.             /* Start the timer. */
  432.  
  433.         StartTime(Config->TransferConfig->SendTimeout / 100,(Config->TransferConfig->SendTimeout % 100) * 10000);
  434.  
  435.             /* Loop until we got an echo or the bell rings. */
  436.  
  437.         GotIt = FALSE;
  438.  
  439.         do
  440.         {
  441.                 /* Wait for something to happen. */
  442.  
  443.             Signals = (*SerialWaitForData)(SIG_TIMER);
  444.  
  445.                 /* Did we receive any data? */
  446.  
  447.             if(Signals & SIG_SERIAL)
  448.             {
  449.                 if((*SerialGetWaiting)())
  450.                 {
  451.                     if((*SerialRead)(ReadBuffer,1))
  452.                     {
  453.                         BytesIn++;
  454.  
  455.                         if(!Config->TransferConfig->QuietTransfer)
  456.                             ConProcess(ReadBuffer,1);
  457.  
  458.                         GotIt = TRUE;
  459.                     }
  460.                 }
  461.             }
  462.  
  463.                 /* Did the timer elapse? */
  464.  
  465.             if(Signals & SIG_TIMER)
  466.                 break;
  467.         }
  468.         while(!GotIt);
  469.  
  470.             /* Stop the timer. */
  471.  
  472.         StopTime();
  473.  
  474.             /* Check if we got the echo. If not, return an error. */
  475.  
  476.         if(!GotIt)
  477.         {
  478.             Unlock_xOFF();
  479.             return(FALSE);
  480.         }
  481.  
  482.             /* Skip to the next character in the line. */
  483.  
  484.         Line++;
  485.     }
  486.  
  487.     Unlock_xOFF();
  488.  
  489.     return(TRUE);
  490. }
  491.  
  492.     /* ASCIISendSetup():
  493.      *
  494.      *    Choose the right routine for the text line output job.
  495.      */
  496.  
  497. VOID
  498. ASCIISendSetup()
  499. {
  500.         /* Pick the line send routine. */
  501.  
  502.     switch(Config->TransferConfig->PacingMode)
  503.     {
  504.         case PACE_DIRECT:
  505.  
  506.             ASCIISendLine = (SENDLINE)SendLineSimple;
  507.             break;
  508.  
  509.         case PACE_ECHO:
  510.  
  511.             if(Config->TransferConfig->SendTimeout)
  512.                 ASCIISendLine = (SENDLINE)ASCIISendLineEcho;
  513.             else
  514.                 ASCIISendLine = (SENDLINE)SendLineSimple;
  515.  
  516.             break;
  517.  
  518.         case PACE_ANYECHO:
  519.  
  520.             if(Config->TransferConfig->SendTimeout)
  521.                 ASCIISendLine = (SENDLINE)ASCIISendLineAnyEcho;
  522.             else
  523.                 ASCIISendLine = (SENDLINE)SendLineSimple;
  524.  
  525.             break;
  526.  
  527.         case PACE_PROMPT:
  528.  
  529.             if(Config->TransferConfig->SendTimeout)
  530.             {
  531.                     /* Prepare the prompt string. */
  532.  
  533.                 if(Config->TransferConfig->LinePrompt[0])
  534.                     ASCIISendPromptLen = TranslateString(Config->TransferConfig->LinePrompt,ASCIISendPrompt);
  535.                 else
  536.                 {
  537.                     ASCIISendPrompt[0] = 0;
  538.                     ASCIISendPromptLen = 0;
  539.                 }
  540.  
  541.                 ASCIISendLine = (SENDLINE)ASCIISendLinePrompt;
  542.             }
  543.             else
  544.                 ASCIISendLine = (SENDLINE)SendLineSimple;
  545.  
  546.             break;
  547.  
  548.         case PACE_DELAY:
  549.  
  550.             if(Config->TransferConfig->LineDelay || Config->TransferConfig->CharDelay)
  551.                 ASCIISendLine = (SENDLINE)ASCIISendLineDelay;
  552.             else
  553.                 ASCIISendLine = (SENDLINE)SendLineSimple;
  554.  
  555.             break;
  556.  
  557.         case PACE_KEYBOARD:
  558.  
  559.             ASCIISendLine = (SENDLINE)SendLineKeyDelay;
  560.             break;
  561.     }
  562. }
  563.  
  564. BOOL
  565. InternalASCIIUpload(STRPTR SingleFile,BOOL WaitForIt)
  566. {
  567.     BOOL DidSend = FALSE;
  568.     BPTR NewDir,OldDir;
  569.  
  570.         /* We are uploading data. */
  571.  
  572.     Uploading = TRUE;
  573.  
  574.         /* Change to the drawer uploads are going to start from. */
  575.  
  576.     if(NewDir = Lock(Config->PathConfig->ASCIIUploadPath,SHARED_LOCK))
  577.         OldDir = CurrentDir(NewDir);
  578.     else
  579.         OldDir = NULL;
  580.  
  581.     BlockWindows();
  582.  
  583.         /* Check if we must collect the names of the files to send. */
  584.  
  585.     if(!FileTransferInfo)
  586.     {
  587.         if(SingleFile)
  588.         {
  589.             ULONG Size;
  590.  
  591.             if(Size = GetFileSize(SingleFile))
  592.             {
  593.                 if(FileTransferInfo = AllocFileTransferInfo())
  594.                 {
  595.                     if(!AddFileTransferNode(FileTransferInfo,SingleFile,Size))
  596.                     {
  597.                         FreeFileTransferInfo(FileTransferInfo);
  598.  
  599.                         FileTransferInfo = NULL;
  600.                     }
  601.                 }
  602.             }
  603.         }
  604.         else
  605.         {
  606.             struct FileRequester *FileRequest;
  607.             UBYTE DummyBuffer[MAX_FILENAME_LENGTH];
  608.  
  609.             strcpy(DummyBuffer,Config->PathConfig->ASCIIUploadPath);
  610.  
  611.             if(FileRequest = OpenSeveralFiles(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + TRANSFER_ASCII),LocaleString(MSG_TERMTRANSFER_SEND_TXT),NULL,DummyBuffer,sizeof(DummyBuffer)))
  612.             {
  613.                 *PathPart(DummyBuffer) = 0;
  614.  
  615.                 strcpy(Config->PathConfig->ASCIIUploadPath,DummyBuffer);
  616.  
  617.                 ConfigChanged = TRUE;
  618.  
  619.                 FileTransferInfo = BuildFileTransferInfo(FileRequest);
  620.  
  621.                 FreeAslRequest(FileRequest);
  622.             }
  623.         }
  624.     }
  625.     else
  626.     {
  627.         if(SingleFile)
  628.         {
  629.             ULONG Size;
  630.  
  631.             if(Size = GetFileSize(SingleFile))
  632.             {
  633.                 if(!AddFileTransferNode(FileTransferInfo,SingleFile,Size))
  634.                 {
  635.                     FreeFileTransferInfo(FileTransferInfo);
  636.  
  637.                     FileTransferInfo = NULL;
  638.                 }
  639.             }
  640.         }
  641.     }
  642.  
  643.     TransferAborted    = FALSE;
  644.     TransferFailed    = TRUE;
  645.     TransferError    = FALSE;
  646.  
  647.     if(FileTransferInfo)
  648.     {
  649.         struct Window *ThisWindow;
  650.  
  651.         if(ThisWindow = CreateASCIIWindow(TRUE))
  652.         {
  653.             LONG Chars = 0,Lines = 0,Len,i;
  654.             BOOL Terminated = FALSE;
  655.             struct Buffer *File;
  656.  
  657.                 /* Final preparations. */
  658.  
  659.             FileTransferInfo->DoneSize    = 0;
  660.             FileTransferInfo->DoneFiles    = 0;
  661.  
  662.             FileTransferInfo->CurrentFile    = (struct FileTransferNode *)FileTransferInfo->FileList.mlh_Head;
  663.             FileTransferInfo->CurrentSize    = FileTransferInfo->CurrentFile->Size;
  664.  
  665.             PushStatus(STATUS_UPLOAD);
  666.  
  667.             ASCIISendSetup();
  668.  
  669.                 /* Tell everyone what we are doing. */
  670.  
  671.             PushStatus(STATUS_UPLOAD);
  672.  
  673.                 /* Lock the current xOFF state and clear the xOFF flag. */
  674.  
  675.             Lock_xOFF();
  676.             Clear_xOFF();
  677.  
  678.             while(!Terminated && FileTransferInfo->CurrentFile->MinNode.mln_Succ)
  679.             {
  680.                 if(File = BufferOpen(FileTransferInfo->CurrentFile->Name,"r"))
  681.                 {
  682.                     UBYTE    OtherBuffer[256],
  683.                             DummyBuffer[2 * sizeof(OtherBuffer)];
  684.                     ULONG    Signals;
  685.                     BOOL    LastCR = FALSE,Skipped = FALSE;
  686.                     LONG    Length;
  687.  
  688.                     AddASCIIMessage(LocaleString(MSG_ASCIIPANEL_OPENING_FILE_TXT),FileTransferInfo->CurrentFile->Name);
  689.  
  690.                     while(!Skipped && !Terminated && (Len = BufferRead(File,OtherBuffer,sizeof(OtherBuffer))) > 0)
  691.                     {
  692.                         if(Len = MangleASCIIBuffer(Config->TransferConfig->SendCR,Config->TransferConfig->SendLF,OtherBuffer,Len,DummyBuffer))
  693.                         {
  694.                             for(i = 0 ; i < Len ; i++)
  695.                             {
  696.                                 if(DummyBuffer[i] == '\r')
  697.                                 {
  698.                                     Lines++;
  699.  
  700.                                     LastCR = TRUE;
  701.                                 }
  702.                                 else
  703.                                 {
  704.                                     if(DummyBuffer[i] == '\n' && !LastCR)
  705.                                         Lines++;
  706.  
  707.                                     LastCR = FALSE;
  708.                                 }
  709.                             }
  710.  
  711.                             Chars += Len;
  712.  
  713.                             DidSend = TRUE;
  714.  
  715.                             TransferFailed = FALSE;
  716.  
  717.                             (*ASCIISendLine)(DummyBuffer,Len);
  718.                         }
  719.  
  720.                         Signals = SetSignal(0,SIG_BREAK | PORTMASK(ThisWindow->UserPort)) & (SIG_BREAK | PORTMASK(ThisWindow->UserPort));
  721.  
  722.                         if(Signals & SIG_BREAK)
  723.                             Terminated = TransferAborted = TRUE;
  724.  
  725.                         if(Signals & PORTMASK(ThisWindow->UserPort))
  726.                         {
  727.                             switch(HandleASCIIWindow())
  728.                             {
  729.                                 case 1:
  730.  
  731.                                     Terminated = TransferAborted = TRUE;
  732.                                     break;
  733.  
  734.                                 case 2:
  735.  
  736.                                     Skipped = TRUE;
  737.                                     break;
  738.                             }
  739.  
  740.                             if(Terminated || Skipped)
  741.                                 break;
  742.                         }
  743.  
  744.                         if(Length = (*SerialGetWaiting)())
  745.                         {
  746.                             if(Length > SerialBufferSize)
  747.                                 Length = SerialBufferSize;
  748.  
  749.                             if(Length > Config->SerialConfig->Quantum)
  750.                                 Length = Config->SerialConfig->Quantum;
  751.  
  752.                             if(Length = (*SerialRead)(ReadBuffer,Length))
  753.                             {
  754.                                 BytesIn += Length;
  755.  
  756.                                     /* Send the data to the console. */
  757.  
  758.                                 if(!Config->TransferConfig->QuietTransfer)
  759.                                     ConProcess(ReadBuffer,Length);
  760.                             }
  761.                         }
  762.  
  763.                         UpdateASCIIWindow(Chars,FileTransferInfo->CurrentFile->Size,Lines);
  764.                     }
  765.  
  766.                     if(Len < 0)
  767.                     {
  768.                         AddASCIIMessage(LocaleString(MSG_ASCIIPANEL_ERROR_READING_FILE_TXT),FileTransferInfo->CurrentFile->Name);
  769.  
  770.                         TransferFailed = TRUE;
  771.  
  772.                         break;
  773.                     }
  774.  
  775.                     BufferClose(File);
  776.  
  777.                     RemoveUploadListItem(FileTransferInfo->CurrentFile->Name);
  778.                 }
  779.                 else
  780.                 {
  781.                     AddASCIIMessage(LocaleString(MSG_ASCIIPANEL_ERROR_OPENING_FILE_TXT),FileTransferInfo->CurrentFile->Name);
  782.  
  783.                     TransferFailed = TRUE;
  784.  
  785.                     break;
  786.                 }
  787.  
  788.                 FileTransferInfo->DoneSize    += FileTransferInfo->CurrentSize;
  789.                 FileTransferInfo->DoneFiles    += 1;
  790.  
  791.                 FileTransferInfo->CurrentFile  = (struct FileTransferNode *)FileTransferInfo->CurrentFile->MinNode.mln_Succ;
  792.                 FileTransferInfo->CurrentSize  = FileTransferInfo->CurrentFile->Size;
  793.             }
  794.  
  795.             Unlock_xOFF();
  796.  
  797.             PopStatus();
  798.  
  799.             if(TransferFailed || TransferError)
  800.                 WakeUp(ThisWindow,SOUND_BADTRANSFER);
  801.             else
  802.             {
  803.                 WakeUp(ThisWindow,SOUND_GOODTRANSFER);
  804.  
  805.                 DelayTime(2,0);
  806.             }
  807.  
  808.             DeleteASCIIWindow(ThisWindow,TransferFailed && WaitForIt);
  809.         }
  810.  
  811.         FreeFileTransferInfo(FileTransferInfo);
  812.  
  813.         FileTransferInfo = NULL;
  814.     }
  815.  
  816.     if(TransferFailed || TransferAborted)
  817.         Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  818.     else
  819.         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  820.  
  821.     if(NewDir)
  822.         UnLock(CurrentDir(OldDir));
  823.  
  824.     SendAbort = FALSE;
  825.  
  826.     ReleaseWindows();
  827.  
  828.     DidTransfer = FALSE;
  829.  
  830.     if(WaitForIt)
  831.     {
  832.         if(Config->CommandConfig->DownloadMacro[0])
  833.         {
  834.             SerialCommand(Config->CommandConfig->UploadMacro);
  835.             DidTransfer = FALSE;
  836.         }
  837.     }
  838.  
  839.     return(DidSend);
  840. }
  841.  
  842. BOOL
  843. InternalASCIIDownload(STRPTR Name,BOOL WaitForIt)
  844. {
  845.     UBYTE DummyBuffer[MAX_FILENAME_LENGTH];
  846.     BOOL DidSend = FALSE;
  847.     BPTR NewDir,OldDir;
  848.  
  849.         /* Clear the download list. */
  850.  
  851.     ClearGenericList(GenericListTable[GLIST_DOWNLOAD],FALSE);
  852.  
  853.         /* This is where the files should go into. */
  854.  
  855.     DownloadPath = Config->PathConfig->ASCIIDownloadPath;
  856.  
  857.         /* Is the name empty? */
  858.  
  859.     NewDir = OldDir = NULL;
  860.  
  861.     if(DownloadPath[0])
  862.     {
  863.         if(NewDir = Lock(DownloadPath,ACCESS_READ))
  864.             OldDir = CurrentDir(NewDir);
  865.     }
  866.  
  867.     BlockWindows();
  868.  
  869.         /* Should we ask for a file name? */
  870.  
  871.     if(!Name)
  872.     {
  873.         struct FileRequester *FileRequest;
  874.  
  875.         strcpy(DummyBuffer,DownloadPath);
  876.  
  877.         if(FileRequest = SaveFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + TRANSFER_ASCII),LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),NULL,DummyBuffer,sizeof(DummyBuffer)))
  878.         {
  879.             FreeAslRequest(FileRequest);
  880.  
  881.                 /* Save the download path. */
  882.  
  883.             strcpy(DownloadPath,DummyBuffer);
  884.  
  885.             ConfigChanged = TRUE;
  886.  
  887.             Name = DummyBuffer;
  888.         }
  889.     }
  890.     else
  891.     {
  892.         STRPTR Index;
  893.  
  894.         strcpy(DownloadPath,Name);
  895.  
  896.         Index = PathPart(DownloadPath);
  897.         *Index = 0;
  898.  
  899.         ConfigChanged = TRUE;
  900.     }
  901.  
  902.         /* Final preparations. */
  903.  
  904.     TransferAborted    = FALSE;
  905.     TransferFailed    = TRUE;
  906.     TransferError    = FALSE;
  907.  
  908.         /* Did we get a file name? */
  909.  
  910.     if(Name)
  911.     {
  912.         struct Window *ThisWindow;
  913.  
  914.         if(ThisWindow = CreateASCIIWindow(FALSE))
  915.         {
  916.             struct Buffer *File;
  917.  
  918.             if(File = BufferOpen(Name,"w"))
  919.             {
  920.                 UBYTE OtherBuffer[512];
  921.                 LONG Chars = 0,Lines = 0,i;
  922.                 BOOL Terminated = FALSE;
  923.                 ULONG Signals;
  924.  
  925.                 AddASCIIMessage(LocaleString(MSG_ASCIIPANEL_OPENING_FILE_TXT),Name);
  926.  
  927.                 TransferFailed = FALSE;
  928.  
  929.                     /* We are now downloading. */
  930.  
  931.                 PushStatus(STATUS_DOWNLOAD);
  932.  
  933.                 StartTime(5,0);
  934.  
  935.                     /* Lock the current xOFF state and clear the xOFF flag. */
  936.  
  937.                 Lock_xOFF();
  938.                 Clear_xOFF();
  939.  
  940.                 do
  941.                 {
  942.                     Signals = (*SerialWaitForData)(SIG_BREAK | SIG_TIMER | PORTMASK(ThisWindow->UserPort));
  943.  
  944.                     if(Signals & PORTMASK(ThisWindow->UserPort))
  945.                     {
  946.                         if(HandleASCIIWindow())
  947.                             break;
  948.                     }
  949.  
  950.                     if(Signals & SIG_SERIAL)
  951.                     {
  952.                         LONG Length;
  953.  
  954.                             /* Check how many characters are still waiting to be read. */
  955.  
  956.                         if(Length = (*SerialGetWaiting)())
  957.                         {
  958.                                 /* Stop the timer. */
  959.  
  960.                             StopTime();
  961.  
  962.                                 /* Now determine how many of the waiting data
  963.                                  * we will accept.
  964.                                  */
  965.  
  966.                             if(Length > SerialBufferSize)
  967.                                 Length = SerialBufferSize;
  968.  
  969.                             if(Length > Config->SerialConfig->Quantum)
  970.                                 Length = Config->SerialConfig->Quantum;
  971.  
  972.                             if(Length > sizeof(OtherBuffer) / 2)
  973.                                 Length = sizeof(OtherBuffer) / 2;
  974.  
  975.                                 /* Read the waiting data. */
  976.  
  977.                             if(Length = (*SerialRead)(ReadBuffer,Length))
  978.                             {
  979.                                 BytesIn += Length;
  980.  
  981.                                 if(Length = MangleASCIIBuffer(Config->TransferConfig->ReceiveCR,Config->TransferConfig->ReceiveLF,ReadBuffer,Length,OtherBuffer))
  982.                                 {
  983.                                         /* Send the data to the console. */
  984.  
  985.                                     if(!Config->TransferConfig->QuietTransfer)
  986.                                         ConProcess(ReadBuffer,Length);
  987.  
  988.                                     if(Config->TransferConfig->IgnoreDataPastArnold)
  989.                                     {
  990.                                         for(i = 0 ; i < Length ; i++)
  991.                                         {
  992.                                             if(OtherBuffer[i] == '\r')
  993.                                                 Lines++;
  994.  
  995.                                             if(OtherBuffer[i] == Config->TransferConfig->TerminatorChar)
  996.                                             {
  997.                                                 Length = i;
  998.  
  999.                                                 Terminated = TRUE;
  1000.  
  1001.                                                 break;
  1002.                                             }
  1003.                                         }
  1004.                                     }
  1005.                                     else
  1006.                                     {
  1007.                                         for(i = 0 ; i < Length ; i++)
  1008.                                         {
  1009.                                             if(OtherBuffer[i] == '\r')
  1010.                                                 Lines++;
  1011.                                         }
  1012.                                     }
  1013.  
  1014.                                     if(Length > 0)
  1015.                                     {
  1016.                                         if(BufferWrite(File,OtherBuffer,Length) == Length)
  1017.                                             Chars += Length;
  1018.                                         else
  1019.                                         {
  1020.                                             AddASCIIMessage(LocaleString(MSG_ASCIIPANEL_ERROR_WRITING_FILE_TXT),Name);
  1021.  
  1022.                                             TransferFailed = Terminated = TRUE;
  1023.                                         }
  1024.                                     }
  1025.                                 }
  1026.  
  1027.                                 UpdateASCIIWindow(Chars,0,Lines);
  1028.                             }
  1029.  
  1030.                                 /* Restart the timer and clear the
  1031.                                  * timer wait mask in case we grabbed
  1032.                                  * the new data right at the moment
  1033.                                  * the timeout was about to strike.
  1034.                                  */
  1035.  
  1036.                             StartTime(5,0);
  1037.                             Signals &= ~SIG_TIMER;
  1038.                         }
  1039.                     }
  1040.  
  1041.                     if(Signals & SIG_TIMER)
  1042.                         Terminated = TRUE;
  1043.  
  1044.                     if(Signals & SIG_BREAK)
  1045.                         TransferAborted = Terminated = TRUE;
  1046.                 }
  1047.                 while(!Terminated);
  1048.  
  1049.                 Unlock_xOFF();
  1050.  
  1051.                 PopStatus();
  1052.  
  1053.                 StopTime();
  1054.  
  1055.                 BufferClose(File);
  1056.             }
  1057.             else
  1058.             {
  1059.                 AddASCIIMessage(LocaleString(MSG_ASCIIPANEL_ERROR_OPENING_FILE_TXT),Name);
  1060.  
  1061.                 TransferFailed = TRUE;
  1062.             }
  1063.  
  1064.             if(TransferFailed || TransferError)
  1065.                 WakeUp(ThisWindow,SOUND_BADTRANSFER);
  1066.             else
  1067.             {
  1068.                 WakeUp(ThisWindow,SOUND_GOODTRANSFER);
  1069.  
  1070.                 DelayTime(2,0);
  1071.             }
  1072.  
  1073.             DeleteASCIIWindow(ThisWindow,TransferFailed && WaitForIt);
  1074.         }
  1075.     }
  1076.  
  1077.     if(TransferFailed || TransferAborted)
  1078.         Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1079.     else
  1080.         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1081.  
  1082.     if(NewDir)
  1083.         UnLock(CurrentDir(OldDir));
  1084.  
  1085.     SendAbort = FALSE;
  1086.  
  1087.     ReleaseWindows();
  1088.  
  1089.     DownloadPath = NULL;
  1090.  
  1091.     DidTransfer = FALSE;
  1092.  
  1093.     if(WaitForIt)
  1094.     {
  1095.         if(Config->CommandConfig->DownloadMacro[0])
  1096.         {
  1097.             SerialCommand(Config->CommandConfig->DownloadMacro);
  1098.             DidTransfer = FALSE;
  1099.         }
  1100.     }
  1101.  
  1102.     return(DidSend);
  1103. }
  1104.